package com.sudo.boot.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NioServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel ssc = ServerSocketChannel.open();
        // 设置为非阻塞的方式
        ssc.configureBlocking(false);
        // 设置服务端口
        ssc.socket().bind(new InetSocketAddress(8888));
        // 创建Selector多路复用器
        Selector selector = Selector.open();
        // 把ServerSocketChannel注册到Selector上，并告知对客户端的连接感兴趣
        SelectionKey register = ssc.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            System.out.println("等待事件发生");
            int select = selector.select();
            System.out.println("事件已进入"+select);

            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                if (key.isAcceptable()) {
                    System.out.println("有客户端连接  ");
                    // 服务端
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    // 服务端与客户端建立连接，client 是连接通道
                    SocketChannel client = server.accept();
                    client.configureBlocking(false);
                    client.register(key.selector(), SelectionKey.OP_READ);
                }else if (key.isReadable()) {
                    System.out.println("客户端可读");
                    // 获取服务与客户端连接通道
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    // 创建buffer
                    ByteBuffer recvice = ByteBuffer.allocate(1024);
                    // 将数据写入buffer
                    int len = socketChannel.read(recvice);
                    if (len != -1) {
                        System.out.println("读到客户端的数据：" + new String(recvice.array(),0,len));
                    }
                    // 服务端把数据返回给客户端
                    ByteBuffer send = ByteBuffer.wrap("jie dao shuju".getBytes());
                    // 由通道写数据
                    socketChannel.write(send);
                    // 监听下一次事件，读或写
                    key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                }
                iterator.remove();
            }
        }

    }
}
